<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>菜单管理</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css">
    <style>
        body {
            background-color: #f8f9fa;
            padding: 20px;
        }
        .card {
            border-radius: 10px;
            box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
        }
        .icon-item {
            cursor: pointer;
            transition: all 0.2s;
        }
        .icon-item:hover {
            transform: scale(1.05);
            box-shadow: 0 0.25rem 0.5rem rgba(0, 0, 0, 0.1);
        }
    </style>
</head>
<body>
    <h4 class="mb-4">菜单管理</h4>

    <div class="card">
        <div class="card-body">
            <div class="d-flex justify-content-between mb-3">
                <div class="input-group" style="width: 300px;">
                    <input type="text" id="searchName" class="form-control" placeholder="搜索菜单名称">
                    <button class="btn btn-outline-secondary" type="button" id="btnSearch">
                        <i class="bi bi-search"></i> 搜索
                    </button>
                </div>
                <button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#menuModal" onclick="resetForm()">
                    <i class="bi bi-plus"></i> 新增菜单
                </button>
            </div>
            
            <div class="table-responsive">
                <table class="table table-striped table-hover">
                    <thead>
                        <tr>
                            <th>ID</th>
                            <th>父菜单ID</th>
                            <th>图标</th>
                            <th>菜单名称</th>
                            <th>菜单标识</th>
                            <th>菜单路径</th>
                            <th>是否激活</th>
                            <th>创建时间</th>
                            <th>操作</th>
                        </tr>
                    </thead>
                    <tbody id="menuTableBody">
                        <!-- 菜单数据将通过JavaScript动态加载 -->
                    </tbody>
                </table>
            </div>
            
            <nav aria-label="Page navigation" class="mt-3">
                <ul class="pagination justify-content-center" id="pagination">
                    <!-- 分页将通过JavaScript动态加载 -->
                </ul>
            </nav>
        </div>
    </div>

    <!-- 菜单信息模态框 -->
    <div class="modal fade" id="menuModal" tabindex="-1" aria-labelledby="menuModalLabel" aria-hidden="true">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title" id="menuModalLabel">菜单信息</h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                </div>
                <div class="modal-body">
                    <form id="menuForm">
                        <input type="hidden" id="menuId">
                        <div class="mb-3">
                            <label for="pid" class="form-label">父菜单</label>
                            <select class="form-select" id="pid">
                                <option value="0">顶级菜单</option>
                                <!-- 其他菜单选项将通过JavaScript动态加载 -->
                            </select>
                        </div>
                        <div class="mb-3">
                            <label for="name" class="form-label">菜单名称</label>
                            <input type="text" class="form-control" id="name" required>
                        </div>
                        <div class="mb-3">
                            <label for="code" class="form-label">菜单标识</label>
                            <input type="text" class="form-control" id="code" required>
                            <div class="form-text">唯一标识，例如: user:list</div>
                        </div>
                        <div class="mb-3">
                            <label for="path" class="form-label">菜单路径</label>
                            <input type="text" class="form-control" id="path" required>
                            <div class="form-text">例如: /admin/users</div>
                        </div>
                        <div class="mb-3">
                            <label for="icon" class="form-label">图标</label>
                            <div class="input-group mb-2">
                                <span class="input-group-text"><i id="iconPreview" class="bi bi-grid"></i></span>
                                <input type="text" class="form-control" id="icon" value="bi-grid">
                            </div>
                            <div class="border rounded p-2" style="max-height: 200px; overflow-y: auto;">
                                <div class="mb-2">
                                    <input type="text" class="form-control" id="iconSearch" placeholder="搜索图标">
                                </div>
                                <div class="row row-cols-6 g-2" id="iconContainer">
                                    <!-- 图标列表将通过JavaScript动态加载 -->
                                </div>
                            </div>
                            <div class="form-text">使用Bootstrap图标，例如: bi-grid</div>
                        </div>
                        <div class="mb-3 form-check">
                            <input type="checkbox" class="form-check-input" id="isActive">
                            <label class="form-check-label" for="isActive">是否激活</label>
                        </div>
                    </form>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
                    <button type="button" class="btn btn-primary" id="btnSaveMenu">保存</button>
                </div>
            </div>
        </div>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script>
    <script>
        // 全局变量
        let currentPage = 1;
        let pageSize = 10;
        let currentMenuId = null;
        let allMenus = [];
        
        // Bootstrap图标列表（部分常用图标）
        const bootstrapIcons = [
            'bi-grid', 'bi-house', 'bi-people', 'bi-person', 'bi-gear', 'bi-tools', 'bi-file',
            'bi-folder', 'bi-box', 'bi-archive', 'bi-bell', 'bi-bookmark', 'bi-briefcase',
            'bi-calendar', 'bi-camera', 'bi-cart', 'bi-chat', 'bi-check', 'bi-clipboard',
            'bi-clock', 'bi-cloud', 'bi-code', 'bi-columns', 'bi-command', 'bi-compass',
            'bi-cpu', 'bi-credit-card', 'bi-cursor', 'bi-dash', 'bi-diagram', 'bi-display',
            'bi-door-open', 'bi-envelope', 'bi-exclamation', 'bi-eye', 'bi-flag', 'bi-graph-up',
            'bi-grid-3x3', 'bi-heart', 'bi-image', 'bi-inbox', 'bi-info', 'bi-journal',
            'bi-key', 'bi-layers', 'bi-lightning', 'bi-link', 'bi-list', 'bi-list-check',
            'bi-lock', 'bi-map', 'bi-mic', 'bi-moon', 'bi-music-note', 'bi-newspaper',
            'bi-paperclip', 'bi-pencil', 'bi-phone', 'bi-pie-chart', 'bi-pin', 'bi-play',
            'bi-plus', 'bi-power', 'bi-printer', 'bi-puzzle', 'bi-question', 'bi-receipt',
            'bi-shield', 'bi-shop', 'bi-shuffle', 'bi-star', 'bi-tag', 'bi-trash',
            'bi-trophy', 'bi-truck', 'bi-tv', 'bi-upload', 'bi-vector-pen', 'bi-wallet',
            'bi-wrench', 'bi-x', 'bi-zoom-in'
        ];
        
        // 页面加载完成后执行
        $(document).ready(function() {
            // 设置AJAX请求头部添加token
            $.ajaxSetup({
                beforeSend: function(xhr) {
                    const token = localStorage.getItem('token');
                    if (token) {
                        xhr.setRequestHeader('Authorization', 'Bearer ' + token);
                    }
                },
                error: function(xhr) {
                    if (xhr.status === 401) {
                        // 认证失败，可以通知父窗口处理
                        if (window.parent && window.parent.Auth) {
                            window.parent.Auth.logout();
                        }
                    }
                }
            });
            
            // 加载菜单列表
            loadMenus();
            
            // 绑定搜索按钮事件
            $('#btnSearch').click(function() {
                currentPage = 1;
                loadMenus();
            });
            
            // 回车键搜索
            $('#searchName').keypress(function(e) {
                if (e.which === 13) {
                    currentPage = 1;
                    loadMenus();
                }
            });
            
            // 保存菜单信息
            $('#btnSaveMenu').click(saveMenu);
            
            // 监听图标输入框变化，实时预览
            $('#icon').on('input', function() {
                updateIconPreview();
            });
            
            // 加载图标列表
            loadIconList();
            
            // 图标搜索
            $('#iconSearch').on('input', function() {
                filterIcons($(this).val());
            });
        });
        
        // 更新图标预览
        function updateIconPreview() {
            const iconClass = $('#icon').val();
            $('#iconPreview').attr('class', `bi ${iconClass}`);
        }
        
        // 加载图标列表
        function loadIconList() {
            const container = $('#iconContainer');
            container.empty();
            
            bootstrapIcons.forEach(icon => {
                container.append(`
                    <div class="col icon-item" data-icon="${icon}">
                        <div class="d-flex flex-column align-items-center p-2 border rounded text-center icon-select-item" style="cursor: pointer;">
                            <i class="bi ${icon} mb-2" style="font-size: 1.5rem;"></i>
                            <small>${icon}</small>
                        </div>
                    </div>
                `);
            });
            
            // 绑定图标点击事件
            $('.icon-select-item').click(function() {
                const selectedIcon = $(this).parent().data('icon');
                $('#icon').val(selectedIcon);
                updateIconPreview();
            });
        }
        
        // 过滤图标
        function filterIcons(searchText) {
            if (!searchText) {
                $('.icon-item').show();
                return;
            }
            
            searchText = searchText.toLowerCase();
            $('.icon-item').each(function() {
                const iconName = $(this).data('icon').toLowerCase();
                if (iconName.includes(searchText)) {
                    $(this).show();
                } else {
                    $(this).hide();
                }
            });
        }
        
        // 加载菜单列表
        function loadMenus() {
            const searchName = $('#searchName').val();
            const skip = (currentPage - 1) * pageSize;
            
            $.ajax({
                url: `/admin/api/menus?skip=${skip}&limit=${pageSize}&name=${searchName}`,
                type: 'GET',
                success: function(response) {
                    allMenus = response.items;
                    renderMenuTable(response.items);
                    // 使用后端返回的分页信息
                    renderPagination(response.total, response.pages);
                    
                    // 加载父菜单选项
                    loadParentMenuOptions();
                },
                error: function(xhr) {
                    alert('加载菜单列表失败: ' + xhr.responseJSON?.detail || '未知错误');
                }
            });
        }
        
        // 渲染菜单表格
        function renderMenuTable(menus) {
            const tableBody = $('#menuTableBody');
            tableBody.empty();
            
            if (menus.length === 0) {
                tableBody.append(`<tr><td colspan="9" class="text-center">没有找到菜单</td></tr>`);
                return;
            }
            
            menus.forEach(menu => {
                tableBody.append(`
                    <tr>
                        <td>${menu.id}</td>
                        <td>${menu.pid}</td>
                        <td><i class="bi ${menu.icon || 'bi-grid'}"></i></td>
                        <td>${menu.name}</td>
                        <td>${menu.code}</td>
                        <td>${menu.path}</td>
                        <td>${menu.is_active ? '是' : '否'}</td>
                        <td>${new Date(menu.created_at).toLocaleString()}</td>
                        <td>
                            <button class="btn btn-sm btn-outline-primary me-1" onclick="editMenu(${menu.id})">
                                <i class="bi bi-pencil"></i>
                            </button>
                            <button class="btn btn-sm btn-outline-danger" onclick="deleteMenu(${menu.id})">
                                <i class="bi bi-trash"></i>
                            </button>
                        </td>
                    </tr>
                `);
            });
        }
        
        // 渲染分页
        function renderPagination(totalItems, totalPages) {
            const pagination = $('#pagination');
            pagination.empty();
            
            // 如果没有数据，不显示分页
            if (totalItems === 0) {
                return;
            }
            
            // 计算显示的页码范围（最多显示5页）
            let startPage = Math.max(currentPage - 2, 1);
            let endPage = Math.min(startPage + 4, totalPages);
            
            if (endPage - startPage < 4) {
                startPage = Math.max(endPage - 4, 1);
            }
            
            // 上一页
            pagination.append(`
                <li class="page-item ${currentPage === 1 ? 'disabled' : ''}">
                    <a class="page-link" href="#" onclick="changePage(${currentPage - 1}); return false;">上一页</a>
                </li>
            `);
            
            // 第一页
            if (startPage > 1) {
                pagination.append(`
                    <li class="page-item">
                        <a class="page-link" href="#" onclick="changePage(1); return false;">1</a>
                    </li>
                `);
                
                // 省略号
                if (startPage > 2) {
                    pagination.append(`
                        <li class="page-item disabled">
                            <a class="page-link" href="#">...</a>
                        </li>
                    `);
                }
            }
            
            // 页码
            for (let i = startPage; i <= endPage; i++) {
                pagination.append(`
                    <li class="page-item ${currentPage === i ? 'active' : ''}">
                        <a class="page-link" href="#" onclick="changePage(${i}); return false;">${i}</a>
                    </li>
                `);
            }
            
            // 最后一页
            if (endPage < totalPages) {
                // 省略号
                if (endPage < totalPages - 1) {
                    pagination.append(`
                        <li class="page-item disabled">
                            <a class="page-link" href="#">...</a>
                        </li>
                    `);
                }
                
                pagination.append(`
                    <li class="page-item">
                        <a class="page-link" href="#" onclick="changePage(${totalPages}); return false;">${totalPages}</a>
                    </li>
                `);
            }
            
            // 下一页
            pagination.append(`
                <li class="page-item ${currentPage === totalPages ? 'disabled' : ''}">
                    <a class="page-link" href="#" onclick="changePage(${currentPage + 1}); return false;">下一页</a>
                </li>
            `);
            
            // 显示总记录数和当前页信息
            pagination.append(`
                <li class="page-item disabled ms-2">
                    <a class="page-link" href="#">共 ${totalItems} 条记录，第 ${currentPage}/${totalPages} 页</a>
                </li>
            `);
        }
        
        // 切换页码
        function changePage(page) {
            if (page < 1) return;
            currentPage = page;
            loadMenus();
        }
        
        // 加载父菜单选项
        function loadParentMenuOptions() {
            const pidSelect = $('#pid');
            
            // 清空除了顶级菜单以外的选项
            pidSelect.find('option:not(:first)').remove();
            
            // 如果正在编辑菜单，则不能选择自己或子菜单作为父菜单
            allMenus.forEach(menu => {
                if (!currentMenuId || menu.id != currentMenuId) {
                    pidSelect.append(`<option value="${menu.id}">${menu.name}</option>`);
                }
            });
        }
        
        // 重置表单
        function resetForm() {
            $('#menuId').val('');
            $('#menuForm')[0].reset();
            $('#icon').val('bi-grid');
            updateIconPreview();
            $('#menuModalLabel').text('新增菜单');
            currentMenuId = null;
            loadParentMenuOptions();
        }
        
        // 编辑菜单
        function editMenu(id) {
            currentMenuId = id;
            
            $.ajax({
                url: `/admin/api/menus/${id}`,
                type: 'GET',
                success: function(menu) {
                    $('#menuId').val(menu.id);
                    $('#pid').val(menu.pid);
                    $('#name').val(menu.name);
                    $('#code').val(menu.code);
                    $('#path').val(menu.path);
                    $('#icon').val(menu.icon || 'bi-grid');
                    updateIconPreview();
                    $('#isActive').prop('checked', menu.is_active === 1);
                    
                    $('#menuModalLabel').text('编辑菜单');
                    loadParentMenuOptions();
                    $('#menuModal').modal('show');
                },
                error: function(xhr) {
                    alert('获取菜单信息失败: ' + xhr.responseJSON?.detail || '未知错误');
                }
            });
        }
        
        // 保存菜单
        function saveMenu() {
            const menuData = {
                pid: parseInt($('#pid').val()),
                name: $('#name').val(),
                code: $('#code').val(),
                path: $('#path').val(),
                icon: $('#icon').val(),
                is_active: $('#isActive').is(':checked') ? 1 : 0
            };
            
            if (currentMenuId) {
                // 更新菜单
                $.ajax({
                    url: `/admin/api/menus/${currentMenuId}`,
                    type: 'PUT',
                    contentType: 'application/json',
                    data: JSON.stringify(menuData),
                    success: function(response) {
                        $('#menuModal').modal('hide');
                        loadMenus();
                    },
                    error: function(xhr) {
                        alert('更新菜单失败: ' + xhr.responseJSON?.detail || '未知错误');
                    }
                });
            } else {
                // 新增菜单
                $.ajax({
                    url: '/admin/api/menus',
                    type: 'POST',
                    contentType: 'application/json',
                    data: JSON.stringify(menuData),
                    success: function(response) {
                        $('#menuModal').modal('hide');
                        loadMenus();
                    },
                    error: function(xhr) {
                        alert('新增菜单失败: ' + xhr.responseJSON?.detail || '未知错误');
                    }
                });
            }
        }
        
        // 删除菜单
        function deleteMenu(id) {
            if (!confirm('确定要删除此菜单吗？如果有子菜单，将无法删除。')) return;
            
            $.ajax({
                url: `/admin/api/menus/${id}`,
                type: 'DELETE',
                success: function(response) {
                    loadMenus();
                },
                error: function(xhr) {
                    let message = '删除菜单失败';
                    if (xhr.responseJSON && xhr.responseJSON.detail) {
                        message += ': ' + xhr.responseJSON.detail;
                    }
                    alert(message);
                }
            });
        }
    </script>
</body>
</html> 